home *** CD-ROM | disk | FTP | other *** search
/ CD Concept 6 / CD Concept 06.iso / mac / UTILITAIRE / Little Smalltalk v3.1.4 / C Source / Sources / names.c < prev    next >
Text File  |  1994-09-14  |  5KB  |  179 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.     Written by Tim Budd, Oregon State University, July 1987
  4.  
  5.     Name Table module
  6.  
  7.     A name table is the term used for a Dictionary indexed by symbols.
  8.     There are two name tables used internally by the bytecode interpreter.
  9.     The first is the table, contained in the variable globalNames,
  10.     that contains the names and values of all globally accessible 
  11.     identifiers.  The second is the table of methods associated with
  12.     every class.  Notice that in neither of these cases does the
  13.     system ever put anything INTO the tables, thus there are only
  14.     routines here for reading FROM tables.
  15.  
  16.     One complication of instances of class Symbol is that all
  17.     symbols must be unique, not only so that == will work as expected,
  18.     but so that memory does not get overly clogged up with symbols.
  19.     Thus all symbols are kept in a hash table, and when new symbols
  20.     are created (via newSymbol(), below) they are inserted into this
  21.     table, if not already there.
  22.  
  23.     This module also manages the definition of various symbols that are
  24.     given fixed values for efficiency sake.  These include the objects
  25.     nil, true, false, and various classes.
  26. */
  27.  
  28. # include <stdio.h>
  29. # include <string.h>
  30. # include "env.h"
  31. # include "memory.h"
  32. # include "names.h"
  33.  
  34. #ifdef THINKC
  35. #include "names.proto.h"
  36. #include "news.proto.h"
  37. #include "memory.proto.h"
  38. # ifdef TCL
  39. #   include "tclprim.proto.h"
  40. # else
  41. #   include "winprim.proto.h"
  42. # endif
  43. #else
  44. static int strTest(object key);
  45. static int strTest(object);
  46. #endif
  47.  
  48. noreturn nameTableInsert(object dict, int hash, object key, object value)
  49. {    object table, link, nwLink, nextLink, tablentry;
  50.  
  51.     /* first get the hash table */
  52.     table = basicAt(dict, 1);
  53.  
  54.     if (sizeField(table) < 3)
  55.         sysError("attempt to insert into","too small name table");
  56.     else {
  57.         hash = 3 * ( hash % (sizeField(table) / 3));
  58.         tablentry = basicAt(table, hash+1);
  59.         if ((tablentry == nilobj) || (tablentry == key)) {
  60.             basicAtPut(table, hash+1, key);
  61.             basicAtPut(table, hash+2, value);
  62.             }
  63.         else {
  64.             nwLink = newLink(key, value);
  65.             incr(nwLink);
  66.             link = basicAt(table, hash+3);
  67.             if (link == nilobj) {
  68.                 basicAtPut(table, hash+3, nwLink);
  69.                 }
  70.             else
  71.                 while(1)
  72.                     if (basicAt(link,1) == key) {
  73.                         basicAtPut(link, 2, value);
  74.                         break;
  75.                         }
  76.                     else if ((nextLink = basicAt(link, 3)) == nilobj) {
  77.                         basicAtPut(link, 3, nwLink);
  78.                         break;
  79.                         }
  80.                     else
  81.                         link = nextLink;
  82.             decr(nwLink);
  83.             }
  84.     }
  85. }
  86.  
  87. object hashEachElement(object dict, int hash, int (*fun )(object obj))
  88. {    object table, key, value, link;
  89.     register object *hp;
  90.     int tablesize;
  91.  
  92.     table = basicAt(dict, 1);
  93.  
  94.     /* now see if table is valid */
  95.     if ((tablesize = sizeField(table)) < 3)
  96.         sysError("system error","lookup on null table");
  97.     else {
  98.         hash = 1+ (3 * (hash % (tablesize / 3)));
  99.         hp = sysMemPtr(table) + (hash-1);
  100.         key = *hp++; /* table at: hash */
  101.         value = *hp++; /* table at: hash + 1 */
  102.         if ((key != nilobj) && (*fun)(key)) 
  103.             return value;
  104.         for (link = *hp; link != nilobj; link = *hp) {
  105.             hp = sysMemPtr(link);
  106.             key = *hp++; /* link at: 1 */
  107.             value = *hp++; /* link at: 2 */
  108.             if ((key != nilobj) && (*fun)(key))
  109.                 return value;
  110.             }
  111.     }
  112.     return nilobj;
  113. }
  114.  
  115. int strHash(char *str)
  116. {    register int hash;
  117.     register char *p;
  118.  
  119.     hash = 0;
  120.     for (p = str; *p; p++)
  121.         hash += *p;
  122.     if (hash < 0) hash = - hash;
  123.     /* make sure it can be a smalltalk integer */
  124.     if (hash > 16384)
  125.         hash >>= 2;
  126.     return hash;
  127. }
  128.  
  129. static object objBuffer;
  130. static char   *charBuffer;
  131.  
  132. static int strTest(object key)
  133. {
  134.     if (charPtr(key) && streq(charPtr(key), charBuffer)) {
  135.         objBuffer = key;
  136.         return 1;
  137.         }
  138.     return 0;
  139. }
  140.  
  141. object globalKey(char *str)
  142. {
  143.     objBuffer = nilobj;
  144.     charBuffer = str;
  145.     hashEachElement(symbols, strHash(str), strTest);
  146.     return objBuffer;
  147. }
  148.  
  149. object nameTableLookup(object dict, char *str)
  150. {
  151.     charBuffer = str;
  152.     return hashEachElement(dict, strHash(str), strTest);
  153. }
  154.  
  155. object unSyms[12];
  156. object binSyms[30];
  157.  
  158. char *unStrs[] = {"isNil", "notNil", "value", "new", "class", "size",
  159. "basicSize", "print", "printString", 0};
  160.  
  161. char *binStrs[] = {"+", "-", "<", ">", "<=", ">=", "=", "~=", "*", 
  162. "quo:", "rem:", "bitAnd:", "bitXor:", "==",
  163. ",", "at:", "basicAt:", "do:", "coerce:", "error:", "includesKey:",
  164. "isMemberOf:", "new:", "to:", "value:", "whileTrue:", "addFirst:", "addLast:",
  165. 0};
  166.  
  167. /* initialize common symbols used by the parser and interpreter */
  168. noreturn initCommonSymbols(void)
  169. {    int i;
  170.  
  171.     trueobj = globalSymbol("true");
  172.     falseobj = globalSymbol("false");
  173.     for (i = 0; unStrs[i]; i++)
  174.         unSyms[i] = newSymbol(unStrs[i]);
  175.     for (i = 0; binStrs[i]; i++)
  176.         binSyms[i] = newSymbol(binStrs[i]);
  177. }
  178.  
  179.